package com.appkubes.mall.restful.application.order.order.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.appkubes.common.constants.BaseConstants;
import com.appkubes.common.exception.BusinessException;
import com.appkubes.common.utils.data.date.DateUtils;
import com.appkubes.mall.core.common.constants.MallUserAccountHistoryConstants;
import com.appkubes.mall.core.entity.MallGoods;
import com.appkubes.mall.core.entity.MallOrder;
import com.appkubes.mall.core.entity.MallOrderGoods;
import com.appkubes.mall.core.entity.MallOrderPlan;
import com.appkubes.mall.core.service.impl.BaseMallOrderServiceImpl;
import com.appkubes.mall.restful.application.goods.goods.entity.dto.MallGoodDetailDto;
import com.appkubes.mall.restful.application.goods.goods.service.impl.GoodsServiceImpl;
import com.appkubes.mall.restful.application.goods.sku.entity.vo.SkuStockVO;
import com.appkubes.mall.restful.application.goods.sku.service.GoodsSpecificSkuService;
import com.appkubes.mall.restful.application.order.goods.service.OrderGoodsService;
import com.appkubes.mall.restful.application.order.order.dao.OrderDao;
import com.appkubes.mall.restful.application.order.order.entity.OrderStateEnum;
import com.appkubes.mall.restful.application.order.order.entity.RentModel;
import com.appkubes.mall.restful.application.order.order.entity.dto.GetListOrderResult;
import com.appkubes.mall.restful.application.order.order.entity.dto.OrderPlanDTO;
import com.appkubes.mall.restful.application.order.order.entity.vo.MallOrderGoodsVo;
import com.appkubes.mall.restful.application.order.order.entity.vo.OrderAddVO;
import com.appkubes.mall.restful.application.order.order.entity.vo.OrderVo;
import com.appkubes.mall.restful.application.order.order.service.OrderPlanService;
import com.appkubes.mall.restful.application.order.order.service.OrderService;
import com.appkubes.mall.restful.application.plugin.rent.service.PluginRentService;
import com.appkubes.mall.restful.application.system.config.service.impl.ConfigServiceImpl;
import com.appkubes.mall.restful.application.user.account.account.entity.dto.OrderPayUserAccountDTO;
import com.appkubes.mall.restful.application.user.user.service.UserService;
import com.appkubes.mall.restful.event.event.EventService;
import com.appkubes.mall.restful.event.order.OrderAddEvent;
import com.appkubes.mall.restful.event.order.OrderPayEvent;
import com.appkubes.mall.restful.event.order.entity.OrderAddEventEO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class OrderServiceImpl extends BaseMallOrderServiceImpl implements OrderService {

    @Autowired
    OrderDao orderDao;
    @Resource
    OrderGoodsService orderGoodsService;

    @Resource
    GoodsServiceImpl goodsService;
    @Resource
    UserService userService; //订单模块看到的是用户模块,而不关系用户模块内容的结构关系
    @Resource
    PluginRentService pluginRentService;
    @Resource
    EventService eventService;
    @Autowired
    ConfigServiceImpl configServiceImpl;//系统配置
    @Resource
    OrderPlanService orderPlanService;
    @Resource
    GoodsSpecificSkuService goodsSpecificSkuService;


    @Override
    public List<MallOrder> getUserOrders(String userKey) {
        MallOrder queryOrder = new MallOrder();
        queryOrder.setUserKey(userKey);
        return this.selectListByEntity(queryOrder);

    }

    public List<GetListOrderResult> getList(String queryStr, int page, int limit) {
        return orderDao.getList(queryStr, (page - 1) * limit, limit);
    }


    @Transactional(rollbackFor = Exception.class)
    public void onPayCallback(String orderKey) throws Exception {
        log.info("onPayCallback:{}", orderKey);
        //更新订单记录状态
        MallOrder order = this.getById(orderKey);
        order.setStatus(OrderStateEnum.PAYSUCCESS.value());
        order.setPayTime(DateUtils.DateToTimestamp(new Date()));
        Boolean flag = this.updateById(order);
        if (flag) {
            //订单状态修改正常,则通知其他模块处理
            // 佣金发放
//            this.onOrderPay(orderKey);
            //租赁模块处理
            pluginRentService.paySucOrder(orderKey);
            //事件通知模块
            OrderPayEvent event = new OrderPayEvent(order);
            eventService.publishEvent(event);
        }

    }

    @Transactional(rollbackFor = RuntimeException.class)
    public void usingOrder(OrderVo orderVo) throws RuntimeException {
        MallOrder order = this.getById(orderVo.getOrderKey());
        if (order == null) {
            throw new RuntimeException("未找到订单");
        }
        if (!order.getStatus().equals(OrderStateEnum.SENDING.value())) {
            throw new RuntimeException("订单无法确认收货，联系客服");
        }
        long time = System.currentTimeMillis() / 1000;
        order.setConfirmTime((int) time);
        order.setUpdateTime((int) time);
        order.setStatus(OrderStateEnum.USING.value());
        order.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
        Boolean ret = this.updateById(order);

        // 发放佣金
//        userAccountService.orderConfirm(order.getUserKey(), orderVo.getOrderKey());
        this.onOrderPay(orderVo.getOrderKey());

        //异步调用通过事件机制进行解耦
        OrderAddEvent event = new OrderAddEvent(this);
        OrderAddEventEO eventEO = new OrderAddEventEO();
        BeanUtils.copyProperties(order, eventEO);
        event.setOrderAddEventEO(eventEO);
        eventService.publishEvent(event);

        if ("RENT".equals(order.getFlexType()) && ret) {
            pluginRentService.shipOrder(order.getFlexSegment1(), order.getUserKey(), order.getIsPayFirst());
        }
    }

    @Override
    public void onOrderPay(String orderKey) {
        List<MallOrderGoods> mallOrderGoodsList = orderGoodsService.getOrderGoodsByOrderKey(orderKey, 1);
        MallOrder mallOrder = getById(orderKey);
        for (MallOrderGoods mallOrderGoods : mallOrderGoodsList) {
            MallGoodDetailDto mallGoodDetailDto = goodsService.getRentGoods(mallOrderGoods.getGoodsKey());
            if (mallGoodDetailDto.getCommisionRate().equals(0)) {
                continue;
            }
            OrderPayUserAccountDTO orderPayUserAccountDTO = new OrderPayUserAccountDTO();
            BigDecimal brokerage = mallOrder.getUseDepositMoney().divide(BigDecimal.valueOf(100)).multiply(mallGoodDetailDto.getCommisionRate());

            orderPayUserAccountDTO.setBrokerage(brokerage);
            orderPayUserAccountDTO.setSourceKey(orderKey);
            orderPayUserAccountDTO.setSourceType(MallUserAccountHistoryConstants.SourceType.ORDER.name());
            orderPayUserAccountDTO.setSourceStatus(OrderStateEnum.USING.value());
            userService.onOrderPay(mallOrderGoods.getUserKey(), orderPayUserAccountDTO);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(String orderKey) throws Exception {
        MallOrder order = this.getById(orderKey);
        if (order.getStatus().equals(OrderStateEnum.CANCEL.value())) {
            return true;
        }
        order.setStatus(OrderStateEnum.CANCEL.value());
        order.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
        this.updateById(order);

        //修改订单详细的状态,回补库存
        List<MallOrderGoods> orderGoods = orderGoodsService.getOrderGoodsByOrderKey(orderKey);
        for (MallOrderGoods orderGood : orderGoods) {
            orderGood.setState(BaseConstants.ORDER.CANCEL);
            orderGoodsService.updateById(orderGood);
        }

        //退款
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean applyCancelOrder(String orderKey) throws Exception {
        MallOrder order = this.getById(orderKey);
        if (order.getStatus() == OrderStateEnum.RETURNING.value()) {
            return true;
        }
        //1修改订单状态
        order.setStatus(OrderStateEnum.RETURNING.value());
        order.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
        this.updateById(order);
        //修改订单详细的状态,回补库存
        List<MallOrderGoods> orderGoods = orderGoodsService.getOrderGoodsByOrderKey(orderKey);
        for (MallOrderGoods orderGood : orderGoods) {
            orderGood.setState(BaseConstants.ORDER.RETURNING);
            orderGoodsService.updateById(orderGood);
        }
        return true;
    }


    @Transactional(rollbackFor = BusinessException.class)
    public List<MallOrderGoodsVo> addOrder(MallOrder order, OrderAddVO orderAddVO) throws BusinessException {
        order.setAppKey(null);

        //第一步 存订单
        Boolean result = false;
        int time = DateUtils.DateToTimestamp(new Date());
        order.setOrderNo(DateUtils.parseDateToStr(new Date(), DateUtils.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS) + "" + (int) ((Math.random() * 9 + 1) * 10000));
        order.setExpireTime(time + 30 * 60);
        order.setCreateTime(DateUtils.DateToTimestamp(new Date()));
        order.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
        order.setAppKey(null);
        result = this.save(order);
        if (!result) {
            throw new BusinessException("订单保存失败，请重新下单");
        }
        //第二步 储存商品订单详情
        Boolean ret = this.insertOrderGoods(orderAddVO.getOrderGoodsList(), orderAddVO.getAssociateGoods(), order.getUserKey(), order.getOrderKey());
        if (!ret) {
            throw new BusinessException("储存商品保存失败，请重新下单");
        }
        //第三步判断是否有添加配送计划有的话存入配送计划,没有的话,设置默认计划
        this.setPlanData(orderAddVO.getOrderExtendVo().getGoodses(), order.getOrderKey());

        if ("zulin".equals(orderAddVO.getOrderExtendVo().getUserOrigin())) {
            try {
                // 调用租赁模块
                JSONObject jsonObject = pluginRentService.addZuLinOrder(order, orderAddVO.getRentInfoVo(), orderAddVO.getOrderExtendVo().getGoodses());
                if (jsonObject.getInteger("code") == 200) {
                    JSONObject jsonObject1 = jsonObject.getJSONObject("data");
                    order.setFlexType("RENT");
                    order.setFlexSegment1(jsonObject1.getString("rentOrderKey"));
                    order.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
                    this.updateById(order);
                }
            } catch (Exception e) {
                throw new BusinessException("租赁下单失败");
            }
        }

        return orderAddVO.getOrderGoodsList();
    }


    public RentModel getSpecificCode(JSONArray paramArr) {
        RentModel model = new RentModel();
        for (int i = 0; i < paramArr.size(); i++) {
            JSONObject obj = paramArr.getJSONObject(i);
            model.setRentCode(obj.getString("rent_code"));
            model.setGoodsTitle(obj.getString("name"));
            model.setNum(obj.getInteger("num"));
            model.setCostMoeny(obj.getBigDecimal("cost_price"));
            model.setRentInterestRate(obj.getBigDecimal("rent_interest_rate"));
        }
        return model;
    }

    public Boolean insertOrderGoods(List<MallOrderGoodsVo> goodses, List<MallOrderGoodsVo> additionKeys, String userKey, String orderKey) throws BusinessException {
        Boolean ret = false;
        goodses.addAll(additionKeys);
        for (MallOrderGoodsVo orderGoodsVo : goodses) {
            MallGoods mallGoods;
            if (StringUtils.isEmpty(orderGoodsVo.getAttrNames())) {
                mallGoods = goodsService.getById(orderGoodsVo.getGoodsKey());
            } else {
                String skuCode = goodsService.getSkuCode(orderGoodsVo.getGoodsKey(), orderGoodsVo.getAttrNames());
                mallGoods = goodsService.findBySkuCode(orderGoodsVo.getGoodsKey(), skuCode);

                // 插入前，先判断库存
                SkuStockVO skuStockVO = new SkuStockVO();
                skuStockVO.setCutNum(orderGoodsVo.getNum());
                skuStockVO.setGoodsKey(orderGoodsVo.getGoodsKey());
                skuStockVO.setSkuCode(skuCode);
                boolean cutResult = goodsSpecificSkuService.cutStock(skuStockVO);
                if (!cutResult) {
                    throw  new BusinessException("库存不足");
                }
            }

            MallOrderGoods mallOrderGoods = new MallOrderGoods();
            BeanUtils.copyProperties(mallGoods, mallOrderGoods);

            if (null != orderGoodsVo.getExtendPrice()) {
                mallOrderGoods.setPrice(orderGoodsVo.getExtendPrice());
            }
            if (!StringUtils.isEmpty(orderGoodsVo.getPic())) {
                mallOrderGoods.setPic(orderGoodsVo.getPic());
            }
            mallOrderGoods.setAttrJson(orderGoodsVo.getAttrJson().toJSONString());
            mallOrderGoods.setGoodsName(mallGoods.getName());
            mallOrderGoods.setAttrNames(orderGoodsVo.getAttrNames());
            mallOrderGoods.setNum(orderGoodsVo.getNum());
            mallOrderGoods.setAmount(mallOrderGoods.getPrice().multiply(BigDecimal.valueOf(mallOrderGoods.getNum())));
            mallOrderGoods.setUserKey(userKey);
            mallOrderGoods.setOrderKey(orderKey);
            mallOrderGoods.setGoodsName(mallGoods.getName());
            mallOrderGoods.setCreateTime(DateUtils.DateToTimestamp(new Date()));
            mallOrderGoods.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
            mallOrderGoods.setAppKey(null);
            ret = orderGoodsService.save(mallOrderGoods);
        }
        return ret;
    }

    /**
     * 保存配送计划
     * @param goodes 商品信息(包含配送计划
     * @param orderKey 订单key
     */
    public void setPlanData(String goodes,String orderKey) {
        int time = DateUtils.DateToTimestamp(new Date());//获取当前时间戳
        String day = configServiceImpl.getByKey("delivery_stocking_period","1");
        //判断用户是否选择配送计划单
        //保存计划

        //判断商品信息中是否有配送计划
        JSONArray goodsArr= JSONArray.parseArray(goodes);
        for (int i = 0; i < goodsArr.size(); i++) {
            JSONObject goodesObj = goodsArr.getJSONObject(i);
            //判断是否有配送计划,如果有保存配送计划,没有设置默认的配送计划
            if (goodesObj.getString("plan") != null) {
                JSONArray paramArr = JSONArray.parseArray(goodesObj.getString("plan"));
                for (int j = 0; j < paramArr.size(); j++) {
                    OrderPlanDTO orderPlanDTO = new OrderPlanDTO();
                    JSONObject planObj = paramArr.getJSONObject(j);
                    orderPlanDTO.setGoodsKey(goodesObj.getString("goods_key"));
                    orderPlanDTO.setOrderKey(orderKey);
                    orderPlanDTO.setGoodsName(goodesObj.getString("name"));
                    orderPlanDTO.setAttrKeys("");//默认空
                    orderPlanDTO.setPlanNum(planObj.getInteger("num"));
                    orderPlanDTO.setPlanTime(DateUtils.DateToTimestamp(planObj.getDate("date")));
                    orderPlanDTO.setPic(goodesObj.getString("pic"));
                    MallOrderPlan plan = new MallOrderPlan();
                    BeanUtils.copyProperties(orderPlanDTO, plan);
                    orderPlanService.save(plan);
                }
            }else{
                //设置默认的配送计划
                MallOrderPlan plan = new MallOrderPlan();
                plan.setPlanTime(time + Integer.parseInt(day) * 86400);
                plan.setPlanNum(1);
                plan.setGoodsKey(goodesObj.getString("goods_key"));
                plan.setOrderKey(orderKey);
                plan.setPic(goodesObj.getString("pic"));
                plan.setPrice(goodesObj.getBigDecimal("price"));
                plan.setAttrKeys(null);//无默认值,给空
                plan.setGoodsName(goodesObj.getString("name"));
                plan.setState(BaseConstants.ORDER.UNPAY);
                orderPlanService.save(plan);
            }
        }


    }


}
